
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <io.h>

#include "fsmscript.h"
#include "ScriptParser.h"

#include "state.h"

#include <vector>
using namespace std;

FSMScript::FSMScript(void)
{
}

FSMScript::~FSMScript(void)
{
}

void FSMScript::Load(char* szFilename, FSM* _pFSM)
{
	pCurrentFSM = _pFSM;
	
	ScriptParser parser;
	parser.Create(szFilename);
	parser.RemoveComments("#");

	// the order of names have to correspond to the order of states in fsm->state. 
	// this is for look up purposes only
	vector<char*> stateNames;

	char* nextToken = 0;

	while(nextToken = parser.NextToken(" \t\n"))
	{
		//lets create the transition table.
		if(!_stricmp(nextToken, "Transitions"))
		{
			//next token should be a {
			parser.NextToken();
			
			int currentStateId = 0;
			Event::EventId eventId;
			int outputStateId = 0;

			//now we get the state names
			while(nextToken = parser.NextToken())
			{
				if(!_stricmp(nextToken, "if"))
				{
					// the state
					nextToken = parser.NextToken();
					currentStateId = GetStateId(nextToken, &stateNames);
					
					//this token should be , and
					parser.NextToken();

					//the event
					nextToken = parser.NextToken();
					eventId = GetEventId(nextToken);

					//this should be then
					parser.NextToken();
					nextToken = parser.NextToken();
					outputStateId = GetStateId(nextToken, &stateNames);

					// ********* populate the transition table	
					for(unsigned int i = 0; i < pCurrentFSM->m_states.size(); i++){
						if(pCurrentFSM->m_states[i]->GetId() == outputStateId){
							
							// *********  NOTE: this line creates an entry on teh transition table
							pCurrentFSM->m_table[currentStateId][eventId] = pCurrentFSM->m_states[i];
						}
					}
				}
				if(*nextToken == '}')
					break;
			}
		}

	}
}

int FSMScript::GetStateId(char* stateName, 	vector<char*> *stateNames)
{

	if(pCurrentFSM->m_states.size() < 3)
		return -1;

	if(!_stricmp(stateName, "StateIdle"))
	{
		return pCurrentFSM->m_states[0]->GetId();
	}

	if(!_stricmp(stateName, "StateBlock"))
	{
		return pCurrentFSM->m_states[1]->GetId();
	}

	if(!_stricmp(stateName, "StateFight"))
	{
		return pCurrentFSM->m_states[2]->GetId();
	}

	return -1;
}

Event::EventId FSMScript::GetEventId(char* eventName)
{
	char* token = 0;
	for(unsigned int i = Event::EVENT_ID_FIRST; i < Event::EVENT_ID_LAST; i++)
	{
		if(!_stricmp(eventName, Event::EventNames[i]))
		{
			return (Event::EventId)i;
		}
	}
	return Event::EVENT_ID_LAST;
}